/**
 * Created by ajhin on 1/20/2015.
 */
package com.societyGames.flashForms
{
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

//Stores multiple items. Each item is sized to full size. On drag left or right
//the next item takes all of the space.
public class HorizontalSlideContainer extends Sprite
{
  private var _items:Vector.<DisplayObject> = new Vector.<DisplayObject>();
  private var _desiredHeight:Number;
  private var _desiredWidth:Number;
  private var _lastMouseX:Number; //the last X position during a drag.
  private var _scrollRect:Rectangle = new Rectangle(); //the scroll rect
  private var _itemsWidth:Number; //the right edge of the items.
  private var _hitAreaSprite:Sprite = new Sprite(); //the hit area.

  public function HorizontalSlideContainer()
  {
    this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
    addChild(this._hitAreaSprite);
  }

  private function onMouseDown(event:MouseEvent):void
  {
    this._lastMouseX = event.stageX;
    this.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
    this.stage.addEventListener(MouseEvent.MOUSE_OUT, onMouseCancel);
    this.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseCancel);
  }

  private function onMouseMove(mouseEvent:MouseEvent):void
  {
    setScrollRectX(this._scrollRect.x + this._lastMouseX - mouseEvent.stageX);
    this._lastMouseX = mouseEvent.stageX;
  }

  private function setScrollRectX(value:Number):void
  {
    this._scrollRect.x = value;
    if (this._scrollRect.x < 0)
    {
      this._scrollRect.x = 0;
    }
    else if (this._scrollRect.x > _itemsWidth - this._desiredWidth)
    {
      this._scrollRect.x = _itemsWidth - this._desiredWidth;
    }
    this.scrollRect = this._scrollRect;
  }

  private function onMouseCancel(mouseEvent:MouseEvent = null):void
  {
    this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
    this.stage.removeEventListener(MouseEvent.ROLL_OUT, onMouseCancel);
    this.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseCancel);

    setScrollRectX(Math.round(this._scrollRect.x / this._desiredWidth) * this._desiredWidth);
  }

  public function addItem(item:DisplayObject):void
  {
    var index:int = _items.indexOf(item);
    //If we don't already have it.
    if (index == -1)
    {
      //Add to the vector.
      _items.push(item);
      //Add to display list.
      this.addChild(item);
      //Recalculate graphics.
      calculate();
    }
  }

  private function calculate():void
  {
    _itemsWidth = 0;
    for each (var item:DisplayObject in _items)
    {
      item.width = _desiredWidth;
      item.height = _desiredHeight;
      item.x = _itemsWidth;
      item.y = 0;
      _itemsWidth += _desiredWidth;
    }

    this._hitAreaSprite.graphics.clear();
    if (!isNaN(this._desiredWidth) && !isNaN(this._desiredHeight))
    {
      this._hitAreaSprite.graphics.beginFill(0xFFFFFF, 0.0);
      this._hitAreaSprite.graphics.drawRect(0, 0, this._itemsWidth, this._desiredHeight);
      this._hitAreaSprite.graphics.endFill();
    }
    this.hitArea = this._hitAreaSprite;

    this._scrollRect.width = this._desiredWidth;
    this._scrollRect.height = this._desiredHeight;
    this.scrollRect = this._scrollRect;
  }

  public function removeItem(item:DisplayObject):void
  {
    var index:int = this._items.indexOf(item);
    if (index != -1)
    {
      this._items.slice(index, 1);
      this.removeChild(item);
      calculate();
    }
  }

  public override function set height(value:Number):void
  {
    if (value != this._desiredHeight)
    {
      this._desiredHeight = value;
      calculate(); //Could be calculate height?
    }
  }

  public override function set width(value:Number):void
  {
    if (value != this._desiredWidth)
    {
      this._desiredWidth = value;
      calculate();
    }
  }
}
}
